<?php
/**
 * Created by PhpStorm.
 * User: 小灰灰
 * Date: 2021-05-26
 * Time: 下午2:47:44
 * Info:
 */

namespace app\common\model;

use think\facade\Db;

class AuthRule extends TimeInit
{

    /**
     * 生成菜单,支持三级
     *
     * @param         $menu      array 数组
     * @param string  $app       插件名称
     * @param integer $pid       父级
     *
     * @return bool
     */
    public function createMenu($menu, $app = '', $pid = 0): bool
    {
        if (empty($menu) || ! is_array($menu)) {
            return false;
        }
        foreach ($menu as $key => $value) {
            if (empty($value['title']) || empty($value['name'])) {
                continue;
            }
            $info = Db::name('auth_rule')->where(['node' => $value['name']])->find();
            if ($info && $info['app'] != $app) {
                // 菜单冲突
                continue;
            }

            $value['app'] = $app;
            // 获取父级
            if (isset($value['pid']) && ! is_numeric($value['pid'])) {
                $value['pid'] = $this->where(['node' => $value['pid']])->value('id');
            } else {
                if ($pid) {
                    $value['pid'] = $pid;
                }
            }
            // 路由
            $value['node'] = $value['route'] ?? '';
            // 图标
            $value['icon'] = isset($value['icon']) ? $value['icon'] : (empty($value['child']) ? 'far fa-circle' : 'fas fa-list-ul');
            // 排序
            $value['weigh'] = $value['weigh'] ?? 100;
            // 菜单类型
            if (( ! isset($value['type']) && empty($value['child'])) || (isset($value['type']) && ! in_array($value['type'],
                        [0, 1, 2]) && empty($value['child']))) {
                $value['type'] = 0;
            } else {
                if (( ! isset($value['type']) && ! empty($value['child'])) || (isset($value['type']) && ! in_array($value['type'],
                            [0, 1, 2]) && ! empty($value['child']))) {
                    $value['type'] = 1;
                }
            }
            // 是否追加到快速导航
            $value['is_menu'] = isset($value['is_menu']) ? $value['is_menu'] : ($value['type'] == 1 ? 1 : 0);

            if ($info) {
                self::update($value, ['id' => $info['id']]);
            } else {
                $tempModel = self::create($value);
            }
            $this->createMenu($value['child'] ?? [], $app, $info ? $info['id'] : $tempModel->id);
        }

        return true;
    }

    public function getNodeTreeList()
    {
        $list = $this->order('node asc')->select()->toArray();
        $list = $this->buildNodeTree($list);

        return $list;
    }

    protected function buildNodeTree($list)
    {
        $newList      = [];
        $repeatString = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
        foreach ($list as $vo) {
            if ($vo['type'] == 1) {
                $newList[] = $vo;
                foreach ($list as $v) {
                    if ($v['type'] == 2 && strpos($v['node'], $vo['node'].'/') !== false) {
                        $v['node'] = "{$repeatString}├{$repeatString}".$v['node'];
                        $newList[] = $v;
                    }
                }
            }
        }

        return $newList;
    }

    /**
     * 根据角色ID获取授权节点
     *
     * @param $authId
     *
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getAuthorizeNodeListByAdminId($authId)
    {
        $checkNodeList = (new AuthGroup())->where('id', $authId)->value('rules');
        $authRule      = new AuthRule();
        $nodelList     = $authRule->where('is_auth',
            1)->field('id,node,title,type,is_auth')->order('node asc')->select()->toArray();
        $newNodeList   = [];
        foreach ($nodelList as $vo) {
            if ($vo['type'] == 1) {
                $vo            = array_merge($vo, ['field' => 'node', 'spread' => true]);
                $vo['checked'] = false;
                $vo['title']   = "{$vo['title']}【{$vo['node']}】";
                $children      = [];
                foreach ($nodelList as $v) {
                    $v['checked'] = false;
                    if ($v['type'] == 2 && strpos($v['node'], $vo['node'].'/') !== false) {
                        $v = array_merge($v, ['field' => 'node', 'spread' => true]);
                        if ($checkNodeList != '*') {
                            $checkNodeArr = explode(',', $checkNodeList);
                            $v['checked'] = in_array($v['id'], $checkNodeArr) ? true : false;
                        }
                        $v['title'] = "{$v['title']}【{$v['node']}】";
                        $children[] = $v;
                    }
                }
                ! empty($children) && $vo['children'] = $children;
                $newNodeList[] = $vo;
            }
        }

        return $newNodeList;
    }

    /**
     * 获取权限列表
     * @return array|\int[][]|\string[][]
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public static function getPidMenuList()
    {
        $list        = AuthRule::field('id,pid,title')->where(['delete_time' => 0])->select();
        $pidMenuList = self::buildPidMenu(0, $list);
        $pidMenuList = array_merge([
            [
                'id'    => 0,
                'pid'   => 0,
                'title' => '顶级菜单',
            ]
        ], $pidMenuList);

        return $pidMenuList;
    }

    public static function buildPidMenu($pid, $list, $level = 0)
    {
        $newList = [];
        foreach ($list as $vo) {
            if ($vo['pid'] == $pid) {
                $level++;
                foreach ($newList as $v) {
                    if ($vo['pid'] == $v['pid'] && isset($v['level'])) {
                        $level = $v['level'];
                        break;
                    }
                }
                $vo['level'] = $level;
                if ($level > 1) {
                    $repeatString = "----";
                    $markString   = str_repeat("│{$repeatString}", $level - 1);
                    $vo['title']  = $markString.$vo['title'];
                }
                $newList[] = $vo;
                $childList = self::buildPidMenu($vo['id'], $list, $level);
                ! empty($childList) && $newList = array_merge($newList, $childList);
            }

        }

        return $newList;
    }

}
